home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i079: Flex, a lex replacement, Part01/05
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Vern Paxson <vern@lbl-csam.arpa>
- Posting-number: Volume 14, Issue 79
- Archive-name: flex/part01
-
- This is the initial release of flex, a replacement for the lex(1) tool.
- As the copyright indicates, this distribution can be freely
- redistributed.
-
- Yes, there are some niggling lex features which are not available which
- seem like they'd be easy to add. They're not, or if they are then the
- straight-forward implementation of them would slow down the scanner.
- Unfortunately I am unable to do any further work on flex other than bug
- fixes, so if there's something you've just gotta have, you'd better be
- willing to dive into the code. I'll be happy to give (fairly high-level)
- advice on how to proceed.
-
- Flex runs on Sun and 4.3 Unix. For a System V machine, add the #define
- "SV". Not guaranteed to do the full job, but a step in the right
- direction. Work is being done on an MS-DOS port.
-
- For more details on the installation, see the README.
-
- Please send problems and feedback to:
-
- vern@lbl-{csam,rtsg}.arpa or ucbvax!lbl-csam.arpa!vern
-
- Vern Paxson
- Real Time Systems Group
- Bldg. 46A
- Lawrence Berkeley Laboratory
- 1 Cyclotron Rd.
- Berkeley, CA 94720
-
- (415) 486-6411
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 5)."
- # Contents: Changes MANIFEST Makefile README Timings ccl.c ecs.c
- # fastskeldef.h flex.skel flexskelcom.h flexskeldef.h parse.y sym.c
- # yylex.c
- # Wrapped by rsalz@fig.bbn.com on Tue May 3 17:31:25 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Changes' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Changes'\"
- else
- echo shar: Extracting \"'Changes'\" \(861 characters\)
- sed "s/^X//" >'Changes' <<'END_OF_FILE'
- Changes between beta-test release of Feb. '88 and initial release:
- X
- X - many files renamed to remove "flex" prefix
- X - input() routine added to compressed and fast skeletons
- X - unput() routine added to compressed skeleton
- X - -d, -ce support for fast scanners
- X - symbol table extended to avoid ugly casts of ints <-> char *'s;
- X this may relieve MS-DOS woes
- X - actions are now separated with YY_BREAK instead of simple "break"'s
- X - fixed bug causing core-dumps if skeleton file could not be opened
- X - fixed bugs in logic deciding which options cannot be intermixed
- X - initial start condition can now be referred to as <INITIAL>
- X - fixed bug which would incorrectly computer trailing context
- X count for a pattern like "(foo){3}"; now this is considered
- X "variable length", even though it isn't.
- X - block comments allowed between rules
- X - misc. typos corrected
- END_OF_FILE
- if test 861 -ne `wc -c <'Changes'`; then
- echo shar: \"'Changes'\" unpacked with wrong size!
- fi
- # end of 'Changes'
- fi
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(858 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X Changes 1
- X MANIFEST 1 This shipping list
- X Makefile 1
- X README 1
- X Timings 1
- X ccl.c 1
- X dfa.c 2
- X ecs.c 1
- X fastskeldef.h 1
- X flex.1 3
- X flex.fastskel 2
- X flex.skel 1
- X flexdef.h 3
- X flexskelcom.h 1
- X flexskeldef.h 1
- X main.c 2
- X misc.c 2
- X nfa.c 3
- X parse.y 1
- X scan.c.dist 4
- X scan.l 2
- X sym.c 1
- X tblcmp.c 5
- X yylex.c 1
- END_OF_FILE
- if test 858 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1264 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# make file for "flex" tool
- X
- X# the first time around use "make first_flex"
- X
- SKELETON_FILE = \"/usr/local/lib/flex.skel\"
- XF_SKELETON_FILE = \"/usr/local/lib/flex.fastskel\"
- SKELFLAGS = -DDEFAULT_SKELETON_FILE=$(SKELETON_FILE) \
- X -DFAST_SKELETON_FILE=$(F_SKELETON_FILE)
- CFLAGS = -O
- LDFLAGS =
- X
- XFLEX_FLAGS = -ist
- XFLEX = flex
- X
- XFLEXOBJS = \
- X ccl.o \
- X dfa.o \
- X ecs.o \
- X main.o \
- X misc.o \
- X nfa.o \
- X parse.o \
- X scan.o \
- X sym.o \
- X tblcmp.o \
- X yylex.o
- X
- XFLEX_C_SOURCES = \
- X ccl.c \
- X dfa.c \
- X ecs.c \
- X main.c \
- X misc.c \
- X nfa.c \
- X parse.c \
- X scan.c \
- X sym.c \
- X tblcmp.c \
- X yylex.c
- X
- flex : $(FLEXOBJS)
- X cc $(CFLAGS) -o flex $(LDFLAGS) $(FLEXOBJS)
- X
- first_flex:
- X cp scan.c.dist scan.c
- X make $(MFLAGS) flex
- X
- parse.h parse.c : parse.y
- X yacc -d parse.y
- X @mv y.tab.c parse.c
- X @mv y.tab.h parse.h
- X
- X# comment-out the next two lines after a successful "make test" and
- X# comment-in the following two lines.
- X
- scan.c : scan.l
- X $(FLEX) $(FLEX_FLAGS) scan.l >scan.c
- X
- scan.o : scan.c parse.h
- X
- main.o : main.c
- X cc $(CFLAGS) -c $(SKELFLAGS) main.c
- X
- flex.lint : $(FLEX_C_SOURCES)
- X @echo "Expect a \"may be used before set\" and 2 \"unused\"'s
- X lint $(FLEX_C_SOURCES) > flex.lint
- X
- clean :
- X rm -f core errs flex *.o parse.c *.lint parse.h
- X
- test :
- X $(FLEX) $(FLEX_FLAGS) scan.l | diff scan.c -
- END_OF_FILE
- if test 1264 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(3402 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- This is the initial release of flex, a replacement for the lex(1)
- tool. As the copyright indicates, this distribution can be freely
- redistributed.
- X
- Some notes on the distribution:
- X
- X Yes, there are some niggling lex features which are not available which
- X seem like they'd be easy to add. They're not, or if they are then the
- X straight-forward implementation of them would slow down the scanner.
- X Unfortunately I am unable to do any further work on flex other than bug
- X fixes, so if there's something you've just gotta have, you'd better
- X be willing to dive into the code. I'll be happy to give (fairly
- X high-level) advice on how to proceed.
- X
- X The compressed tables have been tested pretty thoroughly in the past,
- X though may be suffering from bit-rot. The fast/full tables have been
- X recently implemented and are more likely to have bugs.
- X
- X For a System V machine, add the #define "SV". Not guaranteed to do
- X the full job, but a step in the right direction.
- X
- X Flex has been successfully ported to Sun Unix and 4.3BSD Vax Unix.
- X
- X
- The flex distribution consists of the following files:
- X
- X README This message
- X
- X Changes Differences between this release and the beta-test
- X
- X Makefile
- X flexdef.h
- X parse.y
- X scan.l
- X ccl.c
- X dfa.c flex sources
- X ecs.c
- X main.c
- X misc.c
- X nfa.c
- X sym.c
- X tblcmp.c
- X yylex.c
- X
- X scan.c.dist pre-flex'd version of scan.l
- X
- X flex.skel
- X flex.fastskel
- X flexskelcom.h skeleton scanner sources
- X flexskeldef.h
- X fastskeldef.h
- X
- X flex.1 manual entry
- X
- X Timings a brief note comparing timings of flex vs. lex
- X
- X[ The following section is only true if you got the files from FTP
- X to LBL, directly, and not from the more widely-distributed
- X comp.sources.unix publication. --Rich $alz
- The files are packaged as a compressed shell archive, which in turn
- contains seven shell archives. Create a directory where you want flex
- to live, cd there, and use
- X
- X uncompress flex.shar.Z
- X sh flex.shar
- X
- X sh flex.shar.1
- X sh flex.shar.2
- X sh flex.shar.3
- X sh flex.shar.4
- X sh flex.shar.5
- X sh flex.shar.6
- X sh flex.shar.7
- X
- to extract them.
- X]
- X
- Either move {flexskelcom.h,flexskeldef.h,fastskeldef.h} into /usr/include
- or edit {flex.skel,flex.fastskel,flexskeldef.h,fastskeldef.h,scan.c.dist}
- and wire in the full pathname of where you are going to keep the include files.
- X
- Decide where you want to keep {flex.skel,flex.fastskel} (suggestion:
- X/usr/local/lib) and move it there. Edit "Makefile" and change the
- definitions of SKELETON_FILE and F_SKELETON_FILE to reflect the full
- pathnames of {flex.skel,flex.fastskel}.
- X
- To make flex for the first time, use:
- X
- X make first_flex
- X
- which uses a pre-generated copy of the scanner whose source is in flex.
- X
- Assuming it builds successfully, you can test it using
- X
- X make test
- X
- The "diff" should not show any differences.
- X
- If you're feeling adventurous, rebuild scan.c using various
- combinations of FLEX_FLAGS, each time trying "make test" when
- you're done. To rebuild it, do
- X
- X rm scan.c
- X make FLEX_FLAGS="..."
- X
- where "..." is one of:
- X
- X -ist -c
- X -ist -ce
- X -ist -cm
- X -ist -cfe
- X -ist -cFe
- X
- and testing using:
- X
- X make FLEX_FLAGS="..." test
- X
- X
- XFormat the manual entry using
- X
- X nroff -man flex.1
- X
- X
- Please send problems and feedback to:
- X
- X vern@lbl-{csam,rtsg}.arpa or ucbvax!lbl-csam.arpa!vern
- X
- X Vern Paxson
- X Real Time Systems Group
- X Bldg. 46A
- X Lawrence Berkeley Laboratory
- X 1 Cyclotron Rd.
- X Berkeley, CA 94720
- X
- X (415) 486-6411
- END_OF_FILE
- if test 3402 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'Timings' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Timings'\"
- else
- echo shar: Extracting \"'Timings'\" \(857 characters\)
- sed "s/^X//" >'Timings' <<'END_OF_FILE'
- flex vs. lex timings for a C tokenizer which includes keywords:
- X
- Generation times:
- X
- X lex 83.0 secs
- X flex 3.9
- X flex -cfe 7.1 # uncompressed table, equivalence classes
- X flex -cf 15.0 # uncompressed table, no equivalence classes
- X
- Scanner object file sizes:
- X
- X lex 41.0K bytes
- X flex 9.4K
- X flex -cfe 49.6K
- X flex -cf 126.5K
- X
- Running times on a 28,088 line input (685K characters):
- X
- X lex 29.8 secs
- X flex 19.3
- X flex -cfe 9.0
- X flex -cf 7.8
- X
- The timings were made on a Sun 3/60. All times are user + system CPU time,
- and don't include hashing of identifiers.
- X
- Summary:
- X
- X For about the same sized scanner, you get a factor of 3 in performance.
- X For a 30% faster scanner, you get a scanner 1/4th the size, and it's
- X generated in 1/20th the time.
- X For a scanner that's 3 times larger, you get a factor of 3.8 in
- X performance.
- END_OF_FILE
- if test 857 -ne `wc -c <'Timings'`; then
- echo shar: \"'Timings'\" unpacked with wrong size!
- fi
- # end of 'Timings'
- fi
- if test -f 'ccl.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ccl.c'\"
- else
- echo shar: Extracting \"'ccl.c'\" \(2257 characters\)
- sed "s/^X//" >'ccl.c' <<'END_OF_FILE'
- X/* ccl - routines for character classes */
- X
- X/*
- X * Copyright (c) 1987, the University of California
- X *
- X * The United States Government has rights in this work pursuant to
- X * contract no. DE-AC03-76SF00098 between the United States Department of
- X * Energy and the University of California.
- X *
- X * This program may be redistributed. Enhancements and derivative works
- X * may be created provided the new works, if made available to the general
- X * public, are made available for use by anyone.
- X */
- X
- X#include "flexdef.h"
- X
- X/* ccladd - add a single character to a ccl
- X *
- X * synopsis
- X * int cclp;
- X * char ch;
- X * ccladd( cclp, ch );
- X */
- X
- ccladd( cclp, ch )
- int cclp;
- char ch;
- X
- X {
- X int ind, len, newpos, i;
- X
- X len = ccllen[cclp];
- X ind = cclmap[cclp];
- X
- X /* check to see if the character is already in the ccl */
- X
- X for ( i = 0; i < len; ++i )
- X if ( ccltbl[ind + i] == ch )
- X return;
- X
- X newpos = ind + len;
- X
- X if ( newpos >= current_max_ccl_tbl_size )
- X {
- X current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT;
- X
- X ++num_reallocs;
- X
- X ccltbl = reallocate_character_array( ccltbl, current_max_ccl_tbl_size );
- X }
- X
- X ccllen[cclp] = len + 1;
- X ccltbl[newpos] = ch;
- X }
- X
- X
- X/* cclinit - make an empty ccl
- X *
- X * synopsis
- X * int cclinit();
- X * new_ccl = cclinit();
- X */
- X
- int cclinit()
- X
- X {
- X if ( ++lastccl >= current_maxccls )
- X {
- X current_maxccls += MAXCCLS_INCREMENT;
- X
- X ++num_reallocs;
- X
- X cclmap = reallocate_integer_array( cclmap, current_maxccls );
- X ccllen = reallocate_integer_array( ccllen, current_maxccls );
- X cclng = reallocate_integer_array( cclng, current_maxccls );
- X }
- X
- X if ( lastccl == 1 )
- X /* we're making the first ccl */
- X cclmap[lastccl] = 0;
- X
- X else
- X /* the new pointer is just past the end of the last ccl. Since
- X * the cclmap points to the \first/ character of a ccl, adding the
- X * length of the ccl to the cclmap pointer will produce a cursor
- X * to the first free space
- X */
- X cclmap[lastccl] = cclmap[lastccl - 1] + ccllen[lastccl - 1];
- X
- X ccllen[lastccl] = 0;
- X cclng[lastccl] = 0; /* ccl's start out life un-negated */
- X
- X return ( lastccl );
- X }
- X
- X
- X/* cclnegate - negate a ccl
- X *
- X * synopsis
- X * int cclp;
- X * cclnegate( ccl );
- X */
- X
- cclnegate( cclp )
- int cclp;
- X
- X {
- X cclng[cclp] = 1;
- X }
- END_OF_FILE
- if test 2257 -ne `wc -c <'ccl.c'`; then
- echo shar: \"'ccl.c'\" unpacked with wrong size!
- fi
- # end of 'ccl.c'
- fi
- if test -f 'ecs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ecs.c'\"
- else
- echo shar: Extracting \"'ecs.c'\" \(4546 characters\)
- sed "s/^X//" >'ecs.c' <<'END_OF_FILE'
- X/* ecs - equivalence class routines */
- X
- X/*
- X * Copyright (c) 1987, the University of California
- X *
- X * The United States Government has rights in this work pursuant to
- X * contract no. DE-AC03-76SF00098 between the United States Department of
- X * Energy and the University of California.
- X *
- X * This program may be redistributed. Enhancements and derivative works
- X * may be created provided the new works, if made available to the general
- X * public, are made available for use by anyone.
- X */
- X
- X#include "flexdef.h"
- X
- X/* ccl2ecl - convert character classes to set of equivalence classes
- X *
- X * synopsis
- X * ccl2ecl();
- X */
- X
- ccl2ecl()
- X
- X {
- X int i, ich, newlen, cclp, ccls, cclmec;
- X
- X for ( i = 1; i <= lastccl; ++i )
- X {
- X /* we loop through each character class, and for each character
- X * in the class, add the character's equivalence class to the
- X * new "character" class we are creating. Thus when we are all
- X * done, character classes will really consist of collections
- X * of equivalence classes
- X */
- X
- X newlen = 0;
- X cclp = cclmap[i];
- X
- X for ( ccls = 0; ccls < ccllen[i]; ++ccls )
- X {
- X ich = ccltbl[cclp + ccls];
- X cclmec = ecgroup[ich];
- X if ( cclmec > 0 )
- X {
- X ccltbl[cclp + newlen] = cclmec;
- X ++newlen;
- X }
- X }
- X
- X ccllen[i] = newlen;
- X }
- X }
- X
- X
- X/* cre8ecs - associate equivalence class numbers with class members
- X *
- X * synopsis
- X * int cre8ecs();
- X * number of classes = cre8ecs( fwd, bck, num );
- X *
- X * fwd is the forward linked-list of equivalence class members. bck
- X * is the backward linked-list, and num is the number of class members.
- X * Returned is the number of classes.
- X */
- X
- int cre8ecs( fwd, bck, num )
- int fwd[], bck[], num;
- X
- X {
- X int i, j, numcl;
- X
- X numcl = 0;
- X
- X /* create equivalence class numbers. From now on, abs( bck(x) )
- X * is the equivalence class number for object x. If bck(x)
- X * is positive, then x is the representative of its equivalence
- X * class.
- X */
- X
- X for ( i = 1; i <= num; ++i )
- X if ( bck[i] == NIL )
- X {
- X bck[i] = ++numcl;
- X for ( j = fwd[i]; j != NIL; j = fwd[j] )
- X bck[j] = -numcl;
- X }
- X
- X return ( numcl );
- X }
- X
- X
- X/* mkeccl - update equivalence classes based on character class xtions
- X *
- X * synopsis
- X * char ccls[];
- X * int lenccl, fwd[llsiz], bck[llsiz], llsiz;
- X * mkeccl( ccls, lenccl, fwd, bck, llsiz );
- X *
- X * where ccls contains the elements of the character class, lenccl is the
- X * number of elements in the ccl, fwd is the forward link-list of equivalent
- X * characters, bck is the backward link-list, and llsiz size of the link-list
- X */
- X
- mkeccl( ccls, lenccl, fwd, bck, llsiz )
- char ccls[];
- int lenccl, fwd[], bck[], llsiz;
- X
- X {
- X int cclp, oldec, newec;
- X int cclm, i, j;
- X
- X /* note that it doesn't matter whether or not the character class is
- X * negated. The same results will be obtained in either case.
- X */
- X
- X cclp = 0;
- X
- X while ( cclp < lenccl )
- X {
- X cclm = ccls[cclp];
- X oldec = bck[cclm];
- X newec = cclm;
- X
- X j = cclp + 1;
- X
- X for ( i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i] )
- X { /* look for the symbol in the character class */
- X for ( ; j < lenccl && ccls[j] <= i; ++j )
- X if ( ccls[j] == i )
- X {
- X /* we found an old companion of cclm in the ccl.
- X * link it into the new equivalence class and flag it as
- X * having been processed
- X */
- X
- X bck[i] = newec;
- X fwd[newec] = i;
- X newec = i;
- X ccls[j] = -i; /* set flag so we don't reprocess */
- X
- X /* get next equivalence class member */
- X /* next 2 */ goto next_pt;
- X }
- X
- X /* symbol isn't in character class. Put it in the old equivalence
- X * class
- X */
- X
- X bck[i] = oldec;
- X
- X if ( oldec != NIL )
- X fwd[oldec] = i;
- X
- X oldec = i;
- next_pt:
- X ;
- X }
- X
- X if ( bck[cclm] != NIL || oldec != bck[cclm] )
- X {
- X bck[cclm] = NIL;
- X fwd[oldec] = NIL;
- X }
- X
- X fwd[newec] = NIL;
- X
- X /* find next ccl member to process */
- X
- X for ( ++cclp; ccls[cclp] < 0 && cclp < lenccl; ++cclp )
- X {
- X /* reset "doesn't need processing" flag */
- X ccls[cclp] = -ccls[cclp];
- X }
- X }
- X }
- X
- X
- X/* mkechar - create equivalence class for single character
- X *
- X * synopsis
- X * int tch, fwd[], bck[];
- X * mkechar( tch, fwd, bck );
- X */
- X
- mkechar( tch, fwd, bck )
- int tch, fwd[], bck[];
- X
- X {
- X /* if until now the character has been a proper subset of
- X * an equivalence class, break it away to create a new ec
- X */
- X
- X if ( fwd[tch] != NIL )
- X bck[fwd[tch]] = bck[tch];
- X
- X if ( bck[tch] != NIL )
- X fwd[bck[tch]] = fwd[tch];
- X
- X fwd[tch] = NIL;
- X bck[tch] = NIL;
- X }
- END_OF_FILE
- if test 4546 -ne `wc -c <'ecs.c'`; then
- echo shar: \"'ecs.c'\" unpacked with wrong size!
- fi
- # end of 'ecs.c'
- fi
- if test -f 'fastskeldef.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fastskeldef.h'\"
- else
- echo shar: Extracting \"'fastskeldef.h'\" \(2842 characters\)
- sed "s/^X//" >'fastskeldef.h' <<'END_OF_FILE'
- X/* macro definitions for fast/full-table C/FTL programs generated by flex */
- X
- X#include "flexskelcom.h"
- X
- X#define YY_END_OF_BUFFER_CHAR 0
- X
- X/* action number for "not an accepting state; back-track (not implemented)" */
- X#define YY_BACK_TRACK 0
- X
- X/* action number for end-of-buffer was seen */
- X#define YY_END_OF_BUFFER -3
- X
- X/* reinitializes everything except the current start condition. The last
- X * input character is set to a newline so an initial beginning-of-line
- X * rule will match
- X */
- X#define YY_FAST_INIT \
- X { \
- X yytext = yy_c_buf_p = &yy_ch_buf[1]; \
- X yyleng = 0; \
- X yy_hold_char = *yy_c_buf_p; \
- X }
- X
- X/* done before the next pattern has been matched action
- X * change both of these if you change them at all!
- X */
- X#define YY_DO_BEFORE_SCAN \
- X *yy_c_buf_p = yy_hold_char
- X#define YY_DO_BEFORE_RESTART \
- X yy_hold_char = *yy_c_buf_p
- X
- X/* done after the current pattern has been matched and before the
- X * corresponding action
- X */
- X#define YY_DO_BEFORE_ACTION \
- X yytext = yy_b_buf_p; \
- X yyleng = YY_LENG; \
- X yy_hold_char = *yy_c_buf_p; \
- X *yy_c_buf_p = '\0'
- X
- X/* returns the length of the matched text */
- X#define YY_LENG (yy_c_buf_p - yy_b_buf_p)
- X
- X#ifdef FLEX_FULL_TABLE
- X#define YY_CS_TYPE int
- X#else
- X#define YY_CS_TYPE struct yy_trans_info *
- X#endif
- X
- X/* find starting state */
- X#ifdef FLEX_FULL_TABLE
- X# define YY_FIND_START_STATE( x ) \
- X x = yy_start; \
- X if ( yy_b_buf_p[-1] == '\n' ) \
- X ++x
- X#else
- X# define YY_FIND_START_STATE( x ) \
- X x = yy_state_ptr[yy_start]; \
- X if ( yy_b_buf_p[-1] == '\n' ) \
- X x = yy_state_ptr[yy_start + 1]
- X#endif
- X
- X# ifdef FLEX_USE_ECS
- X# define yy_eq(x) e[x]
- X# else
- X# define yy_eq(x) x
- X# endif
- X
- X/* get next jam state from packed table */
- X#ifdef FLEX_FULL_TABLE
- X# define YY_FIND_NEXT_MATCH \
- X { \
- X register int yy_state_info; \
- X while ( (yy_state_info = n[yy_current_state][yy_eq(*yy_c_buf_p)] ) != YY_JAM ) \
- X { \
- X yy_current_state = yy_state_info; \
- X YY_BACKTRACKING_ACTION \
- X yy_c_buf_p++; \
- X } \
- X }
- X#else
- X# define YY_FIND_NEXT_MATCH \
- X for ( yy_c = yy_eq(*yy_c_buf_p); \
- X (yy_trans_info = &yy_current_state[yy_c])->v == yy_c; \
- X yy_c = yy_eq(*++yy_c_buf_p) ) \
- X { \
- X yy_current_state += yy_trans_info->n; \
- X YY_BACKTRACKING_ACTION \
- X }
- X#endif
- X
- X#ifdef FLEX_FULL_TABLE
- X# define YY_FIND_ACTION( x ) x = l[yy_current_state]
- X#else
- X# define YY_FIND_ACTION( x ) x = yy_current_state[-1].n
- X#endif
- X
- X
- X#ifdef FLEX_FULL_TABLE
- X# define YY_GET_NEXT_STATE yy_cur_state = n[yy_cur_state][*(yy_temp_char_ptr++)]
- X#else
- X# define YY_GET_NEXT_STATE yy_cur_state += yy_cur_state[*(yy_temp_char_ptr++)].n
- X#endif
- X
- X#define EOB_ACT_RESTART_SCAN 2
- X#define EOB_ACT_END_OF_FILE 3
- X#define EOB_ACT_LAST_MATCH 4
- X
- X#ifdef FLEX_FULL_TABLE
- X#define YY_DECLARE_YY_CS_PARAM int *yy_current_state
- X#else
- X#define YY_DECLARE_YY_CS_PARAM struct yy_trans_info *yy_current_state
- X#endif
- END_OF_FILE
- if test 2842 -ne `wc -c <'fastskeldef.h'`; then
- echo shar: \"'fastskeldef.h'\" unpacked with wrong size!
- fi
- # end of 'fastskeldef.h'
- fi
- if test -f 'flex.skel' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'flex.skel'\"
- else
- echo shar: Extracting \"'flex.skel'\" \(6545 characters\)
- sed "s/^X//" >'flex.skel' <<'END_OF_FILE'
- X/* A lexical scanner generated by flex */
- X
- X#include "flexskeldef.h"
- X
- X%% section 1 code and data tables for DFA go here
- X
- X/* these declarations have to come after the section 1 code or lint gets
- X * confused about whether the variables are used
- X */
- XFILE *yyin = stdin, *yyout = stdout;
- X
- X/* these variables are all declared out here so that section 3 code can
- X * manipulate them
- X */
- static int yy_start, yy_b_buf_p, yy_c_buf_p, yy_e_buf_p;
- static int yy_saw_eof, yy_init = 1;
- X
- X/* yy_ch_buf has to be 1 character longer than YY_BUF_SIZE, since when
- X * setting up yytext we can try to put a '\0' just past the end of the
- X * matched text
- X */
- static char yy_ch_buf[YY_BUF_SIZE + 1];
- static int yy_st_buf[YY_BUF_SIZE];
- static char yy_hold_char;
- char *yytext;
- static int yyleng;
- X
- YY_DECL
- X {
- X int yy_n_chars, yy_lp, yy_iii, yy_buf_pos, yy_act;
- X
- X%% user's declarations go here
- X
- X if ( yy_init )
- X {
- X YY_INIT;
- X yy_start = 1;
- X yy_init = 0;
- X }
- X
- X goto get_next_token;
- X
- do_action:
- X for ( ; ; )
- X {
- X YY_DO_BEFORE_ACTION
- X
- X#ifdef FLEX_DEBUG
- X fprintf( stderr, "--accepting rule #%d\n", yy_act );
- X#endif
- X switch ( yy_act )
- X {
- X%% actions go here
- X
- case YY_NEW_FILE:
- break; /* begin reading from new file */
- X
- case YY_DO_DEFAULT:
- YY_DEFAULT_ACTION;
- break;
- X
- case YY_END_TOK:
- return ( YY_END_TOK );
- X
- default:
- YY_FATAL_ERROR( "fatal flex scanner internal error" );
- X }
- X
- get_next_token:
- X {
- X register int yy_curst;
- X register char yy_sym;
- X
- X YY_DO_BEFORE_SCAN
- X
- X /* set up to begin running DFA */
- X
- X yy_curst = yy_start;
- X
- X if ( yy_ch_buf[yy_c_buf_p] == '\n' )
- X ++yy_curst;
- X
- X /* yy_b_buf_p points to the position in yy_ch_buf
- X * of the start of the current run.
- X */
- X
- X yy_b_buf_p = yy_c_buf_p + 1;
- X
- X do /* until the machine jams */
- X {
- X if ( yy_c_buf_p == yy_e_buf_p )
- X { /* need more input */
- X if ( yy_e_buf_p >= YY_BUF_LIM )
- X { /* not enough room to do another read */
- X /* see if we can make some room for more chars */
- X
- X yy_n_chars = yy_e_buf_p - yy_b_buf_p;
- X
- X if ( yy_n_chars >= 0 )
- X /* shift down buffer to make room */
- X for ( yy_iii = 0; yy_iii <= yy_n_chars; ++yy_iii )
- X {
- X yy_buf_pos = yy_b_buf_p + yy_iii;
- X yy_ch_buf[yy_iii] = yy_ch_buf[yy_buf_pos];
- X yy_st_buf[yy_iii] = yy_st_buf[yy_buf_pos];
- X }
- X
- X yy_b_buf_p = 0;
- X yy_e_buf_p = yy_n_chars;
- X
- X if ( yy_e_buf_p >= YY_BUF_LIM )
- X YY_FATAL_ERROR( "flex input buffer overflowed" );
- X
- X yy_c_buf_p = yy_e_buf_p;
- X }
- X
- X else if ( yy_saw_eof )
- X {
- saweof: if ( yy_b_buf_p > yy_e_buf_p )
- X {
- X if ( yywrap() )
- X {
- X yy_act = YY_END_TOK;
- X goto do_action;
- X }
- X
- X else
- X {
- X YY_INIT;
- X yy_act = YY_NEW_FILE;
- X goto do_action;
- X }
- X }
- X
- X else /* do a jam to eat up more input */
- X {
- X#ifndef FLEX_INTERACTIVE_SCANNER
- X /* we're going to decrement yy_c_buf_p upon doing
- X * the jam. In this case, that's wrong, since
- X * it points to the last non-jam character. So
- X * we increment it now to counter the decrement.
- X */
- X ++yy_c_buf_p;
- X#endif
- X break;
- X }
- X }
- X
- X YY_INPUT( (yy_ch_buf + yy_c_buf_p + 1), yy_n_chars,
- X YY_MAX_LINE );
- X
- X if ( yy_n_chars == YY_NULL )
- X {
- X if ( yy_saw_eof )
- X YY_FATAL_ERROR( "flex scanner saw EOF twice - shouldn't happen" );
- X yy_saw_eof = 1;
- X goto saweof;
- X }
- X
- X yy_e_buf_p += yy_n_chars;
- X }
- X
- X ++yy_c_buf_p;
- X
- X#ifdef FLEX_USE_ECS
- X yy_sym = e[yy_ch_buf[yy_c_buf_p]];
- X#else
- X yy_sym = yy_ch_buf[yy_c_buf_p];
- X#endif
- X
- X#ifdef FLEX_FULL_TABLE
- X yy_curst = n[yy_curst][yy_sym];
- X
- X#else /* get next state from compressed table */
- X
- X while ( c[b[yy_curst] + yy_sym] != yy_curst )
- X {
- X yy_curst = d[yy_curst];
- X
- X#ifdef FLEX_USE_MECS
- X /* we've arrange it so that templates are never chained
- X * to one another. This means we can afford make a
- X * very simple test to see if we need to convert to
- X * yy_sym's meta-equivalence class without worrying
- X * about erroneously looking up the meta-equivalence
- X * class twice
- X */
- X
- X if ( yy_curst >= YY_TEMPLATE )
- X yy_sym = m[yy_sym];
- X#endif
- X }
- X
- X yy_curst = n[b[yy_curst] + yy_sym];
- X
- X#endif
- X
- X yy_st_buf[yy_c_buf_p] = yy_curst;
- X
- X }
- X#ifdef FLEX_INTERACTIVE_SCANNER
- X while ( b[yy_curst] != YY_JAM_BASE );
- X#else
- X while ( yy_curst != YY_JAM );
- X --yy_c_buf_p; /* put back character we jammed on */
- X
- X#endif
- X
- X if ( yy_c_buf_p >= yy_b_buf_p )
- X { /* we matched some text */
- X yy_curst = yy_st_buf[yy_c_buf_p];
- X yy_lp = l[yy_curst];
- X
- X#ifdef FLEX_REJECT_ENABLED
- find_rule: /* we branch to this label when doing a REJECT */
- X#endif
- X
- X for ( ; ; ) /* until we find what rule we matched */
- X {
- X#ifdef FLEX_REJECT_ENABLED
- X if ( yy_lp && yy_lp < l[yy_curst + 1] )
- X {
- X yy_act = a[yy_lp];
- X goto do_action; /* "continue 2" */
- X }
- X#else
- X if ( yy_lp )
- X {
- X yy_act = yy_lp;
- X goto do_action; /* "continue 2" */
- X }
- X#endif
- X
- X if ( --yy_c_buf_p < yy_b_buf_p )
- X break;
- X
- X yy_curst = yy_st_buf[yy_c_buf_p];
- X yy_lp = l[yy_curst];
- X }
- X }
- X
- X /* if we got this far, then we didn't find any accepting
- X * states
- X */
- X
- X /* so that the default applies to the first char read */
- X ++yy_c_buf_p;
- X
- X yy_act = YY_DO_DEFAULT;
- X }
- X }
- X
- X /*NOTREACHED*/
- X }
- X
- X
- static int unput( c )
- char c;
- X
- X {
- X YY_DO_BEFORE_SCAN; /* undo effects of setting up yytext */
- X
- X if ( yy_c_buf_p == 0 )
- X {
- X register int i;
- X register int yy_buf_pos = YY_BUF_MAX;
- X
- X for ( i = yy_e_buf_p; i >= yy_c_buf_p; --i )
- X {
- X yy_ch_buf[yy_buf_pos] = yy_ch_buf[i];
- X yy_st_buf[yy_buf_pos] = yy_st_buf[i];
- X --yy_buf_pos;
- X }
- X
- X yy_c_buf_p = YY_BUF_MAX - yy_e_buf_p;
- X yy_e_buf_p = YY_BUF_MAX;
- X }
- X
- X if ( yy_c_buf_p <= 0 )
- X YY_FATAL_ERROR( "flex scanner push-back overflow" );
- X
- X if ( yy_c_buf_p >= yy_b_buf_p && yy_ch_buf[yy_c_buf_p] == '\n' )
- X yy_ch_buf[yy_c_buf_p - 1] = '\n';
- X
- X yy_ch_buf[yy_c_buf_p--] = c;
- X
- X YY_DO_BEFORE_ACTION; /* set up yytext again */
- X }
- X
- X
- static int input()
- X
- X {
- X int c;
- X
- X YY_DO_BEFORE_SCAN
- X
- X if ( yy_c_buf_p == yy_e_buf_p )
- X { /* need more input */
- X int yy_n_chars;
- X
- X /* we can throw away the entire current buffer */
- X if ( yy_saw_eof )
- X {
- X if ( yywrap() )
- X return ( EOF );
- X
- X YY_INIT;
- X }
- X
- X yy_b_buf_p = 0;
- X YY_INPUT( yy_ch_buf, yy_n_chars, YY_MAX_LINE );
- X
- X if ( yy_n_chars == YY_NULL )
- X {
- X yy_saw_eof = 1;
- X
- X if ( yywrap() )
- X return ( EOF );
- X
- X YY_INIT;
- X
- X return ( input() );
- X }
- X
- X yy_c_buf_p = -1;
- X yy_e_buf_p = yy_n_chars - 1;
- X }
- X
- X c = yy_ch_buf[++yy_c_buf_p];
- X
- X YY_DO_BEFORE_ACTION;
- X
- X return ( c );
- X }
- END_OF_FILE
- if test 6545 -ne `wc -c <'flex.skel'`; then
- echo shar: \"'flex.skel'\" unpacked with wrong size!
- fi
- # end of 'flex.skel'
- fi
- if test -f 'flexskelcom.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'flexskelcom.h'\"
- else
- echo shar: Extracting \"'flexskelcom.h'\" \(2400 characters\)
- sed "s/^X//" >'flexskelcom.h' <<'END_OF_FILE'
- X/* common macro definitions for C/FTL programs generated by flex */
- X
- X
- X/* returned upon end-of-file */
- X#define YY_END_TOK 0
- X
- X/* action number for an "end-of-file was seen and yywrap indicated that we
- X * should continue processing"
- X */
- X#define YY_NEW_FILE -1
- X
- X/* action number for "the default action should be done" */
- X#define YY_DO_DEFAULT -2
- X
- X#ifndef BUFSIZ
- X#include <stdio.h>
- X#endif
- X
- X#define YY_BUF_SIZE (BUFSIZ * 2) /* size of input buffer */
- X
- X/* number of characters one rule can match. One less than YY_BUF_SIZE to make
- X * sure we never access beyond the end of an array
- X */
- X#define YY_BUF_MAX (YY_BUF_SIZE - 1)
- X
- X/* we will never use more than the first YY_BUF_LIM + YY_MAX_LINE positions
- X * of the input buffer
- X */
- X#ifndef YY_MAX_LINE
- X#define YY_MAX_LINE BUFSIZ
- X#endif
- X
- X#define YY_BUF_LIM (YY_BUF_MAX - YY_MAX_LINE)
- X
- X/* copy whatever the last rule matched to the standard output */
- X
- X#define ECHO fputs( yytext, yyout )
- X
- X/* gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- X * is returned in "result".
- X */
- X#define YY_INPUT(buf,result,max_size) \
- X if ( (result = read( fileno(yyin), buf, max_size )) < 0 ) \
- X YY_FATAL_ERROR( "read() in flex scanner failed" );
- X#define YY_NULL 0
- X
- X/* macro used to output a character */
- X#define YY_OUTPUT(c) putc( c, yyout );
- X
- X/* report a fatal error */
- X#define YY_FATAL_ERROR(msg) \
- X { \
- X fputs( msg, stderr ); \
- X putc( '\n', stderr ); \
- X exit( 1 ); \
- X }
- X
- X/* returns the first character of the matched text */
- X#define YY_FIRST_CHAR yy_ch_buf[yy_b_buf_p]
- X
- X/* default yywrap function - always treat EOF as an EOF */
- X#define yywrap() 1
- X
- X/* enter a start condition. This macro really ought to take a parameter,
- X * but we do it the disgusting crufty way that old Unix-lex does it
- X */
- X#define BEGIN yy_start = 1 +
- X
- X/* callable from YY_INPUT to set things up so that '%' will match. Proper
- X * usage is "YY_SET_BOL(array,pos)"
- X */
- X#define YY_SET_BOL(array,pos) array[pos - 1] = '\n';
- X
- X/* default declaration of generated scanner - a define so the user can
- X * easily add parameters
- X */
- X#define YY_DECL int yylex()
- X
- X/* return all but the first 'n' matched characters back to the input stream */
- X#define yyless(n) \
- X { \
- X YY_DO_BEFORE_SCAN; /* undo effects of setting up yytext */ \
- X yy_c_buf_p = yy_b_buf_p + n - 1; \
- X YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- X }
- X
- X/* code executed at the end of each rule */
- X#define YY_BREAK break;
- END_OF_FILE
- if test 2400 -ne `wc -c <'flexskelcom.h'`; then
- echo shar: \"'flexskelcom.h'\" unpacked with wrong size!
- fi
- # end of 'flexskelcom.h'
- fi
- if test -f 'flexskeldef.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'flexskeldef.h'\"
- else
- echo shar: Extracting \"'flexskeldef.h'\" \(1197 characters\)
- sed "s/^X//" >'flexskeldef.h' <<'END_OF_FILE'
- X/* macro definitions for compressed-table C/FTL programs generated by flex */
- X
- X#include "flexskelcom.h"
- X
- X/* reinitializes everything except the current start condition. The last
- X * input character is set to a newline so an initial beginning-of-line
- X * rule will match
- X */
- X#define YY_INIT \
- X { \
- X yyleng = yy_c_buf_p = yy_e_buf_p = 0; \
- X yy_hold_char = yy_ch_buf[yy_c_buf_p] = '\n'; \
- X yytext = &yy_ch_buf[yy_c_buf_p]; \
- X yy_saw_eof = 0; \
- X }
- X
- X/* returns the length of the matched text */
- X#define YY_LENG (yy_c_buf_p - yy_b_buf_p + 1)
- X
- X/* done before the next pattern has been matched action */
- X#define YY_DO_BEFORE_SCAN \
- X yytext[yyleng] = yy_hold_char;
- X
- X/* done after the current pattern has been matched and before the corresponding action */
- X#define YY_DO_BEFORE_ACTION \
- X yytext = &yy_ch_buf[yy_b_buf_p]; \
- X yyleng = YY_LENG; \
- X yy_hold_char = yytext[yyleng]; \
- X yytext[yyleng] = '\0';
- X
- X/* find the next rule matched */
- X#ifdef FLEX_REJECT_ENABLED
- X#define REJECT \
- X { \
- X YY_DO_BEFORE_SCAN; /* undo effects of setting up yytext */ \
- X ++yy_lp; \
- X goto find_rule; \
- X }
- X#else
- X#define REJECT YY_FATAL_ERROR( "REJECT used and scanner was not generated using -r" )
- X#endif
- END_OF_FILE
- if test 1197 -ne `wc -c <'flexskeldef.h'`; then
- echo shar: \"'flexskeldef.h'\" unpacked with wrong size!
- fi
- # end of 'flexskeldef.h'
- fi
- if test -f 'parse.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'parse.y'\"
- else
- echo shar: Extracting \"'parse.y'\" \(8861 characters\)
- sed "s/^X//" >'parse.y' <<'END_OF_FILE'
- X/* parse.y - parser for flex input */
- X
- X/*
- X * Copyright (c) 1987, the University of California
- X *
- X * The United States Government has rights in this work pursuant to
- X * contract no. DE-AC03-76SF00098 between the United States Department of
- X * Energy and the University of California.
- X *
- X * This program may be redistributed. Enhancements and derivative works
- X * may be created provided the new works, if made available to the general
- X * public, are made available for use by anyone.
- X */
- X
- X%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL
- X
- X%{
- X#include "flexdef.h"
- X
- int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
- int trlcontxt, xcluflg, cclsorted, varlength;
- char clower();
- X
- static int madeany = false; /* whether we've made the '.' character class */
- X
- X%}
- X
- X%%
- goal : initlex sect1 sect1end sect2
- X ;
- X
- initlex :
- X {
- X /* initialize for processing rules */
- X
- X /* create default DFA start condition */
- X scinstal( "INITIAL", false );
- X }
- X ;
- X
- sect1 : sect1 startconddecl WHITESPACE namelist1 '\n'
- X |
- X | error '\n'
- X { synerr( "unknown error processing section 1" ); }
- X ;
- X
- sect1end : SECTEND
- X ;
- X
- startconddecl : SCDECL
- X {
- X /* these productions are separate from the s1object
- X * rule because the semantics must be done before
- X * we parse the remainder of an s1object
- X */
- X
- X xcluflg = false;
- X }
- X
- X | XSCDECL
- X { xcluflg = true; }
- X ;
- X
- namelist1 : namelist1 WHITESPACE NAME
- X { scinstal( nmstr, xcluflg ); }
- X
- X | NAME
- X { scinstal( nmstr, xcluflg ); }
- X
- X | error
- X { synerr( "bad start condition list" ); }
- X ;
- X
- sect2 : sect2 initforrule flexrule '\n'
- X |
- X ;
- X
- initforrule :
- X {
- X /* initialize for a parse of one rule */
- X trlcontxt = varlength = false;
- X trailcnt = headcnt = rulelen = 0;
- X }
- X ;
- X
- flexrule : scon '^' re eol
- X {
- X pat = link_machines( $3, $4 );
- X add_accept( pat, headcnt, trailcnt );
- X
- X for ( i = 1; i <= actvp; ++i )
- X scbol[actvsc[i]] = mkbranch( scbol[actvsc[i]], pat );
- X }
- X
- X | scon re eol
- X {
- X pat = link_machines( $2, $3 );
- X add_accept( pat, headcnt, trailcnt );
- X
- X for ( i = 1; i <= actvp; ++i )
- X scset[actvsc[i]] = mkbranch( scset[actvsc[i]], pat );
- X }
- X
- X | '^' re eol
- X {
- X pat = link_machines( $2, $3 );
- X add_accept( pat, headcnt, trailcnt );
- X
- X /* add to all non-exclusive start conditions,
- X * including the default (0) start condition
- X */
- X
- X for ( i = 1; i <= lastsc; ++i )
- X if ( ! scxclu[i] )
- X scbol[i] = mkbranch( scbol[i], pat );
- X }
- X
- X | re eol
- X {
- X pat = link_machines( $1, $2 );
- X add_accept( pat, headcnt, trailcnt );
- X
- X for ( i = 1; i <= lastsc; ++i )
- X if ( ! scxclu[i] )
- X scset[i] = mkbranch( scset[i], pat );
- X }
- X
- X | error
- X { synerr( "unrecognized rule" ); }
- X ;
- X
- scon : '<' namelist2 '>'
- X ;
- X
- namelist2 : namelist2 ',' NAME
- X {
- X if ( (scnum = sclookup( nmstr )) == 0 )
- X synerr( "undeclared start condition" );
- X
- X else
- X actvsc[++actvp] = scnum;
- X }
- X
- X | NAME
- X {
- X if ( (scnum = sclookup( nmstr )) == 0 )
- X synerr( "undeclared start condition" );
- X else
- X actvsc[actvp = 1] = scnum;
- X }
- X
- X | error
- X { synerr( "bad start condition list" ); }
- X ;
- X
- eol : '$'
- X {
- X if ( trlcontxt )
- X {
- X synerr( "trailing context used twice" );
- X $$ = mkstate( SYM_EPSILON );
- X }
- X else
- X {
- X trlcontxt = true;
- X
- X if ( ! varlength )
- X headcnt = rulelen;
- X
- X ++rulelen;
- X trailcnt = 1;
- X
- X eps = mkstate( SYM_EPSILON );
- X $$ = link_machines( eps, mkstate( '\n' ) );
- X }
- X }
- X
- X |
- X {
- X $$ = mkstate( SYM_EPSILON );
- X
- X if ( trlcontxt )
- X {
- X if ( varlength && headcnt == 0 )
- X /* both head and trail are variable-length */
- X synerr( "illegal trailing context" );
- X
- X else
- X trailcnt = rulelen;
- X }
- X }
- X ;
- X
- re : re '|' series
- X {
- X varlength = true;
- X
- X $$ = mkor( $1, $3 );
- X }
- X
- X | re2 series
- X { $$ = link_machines( $1, $2 ); }
- X
- X | series
- X { $$ = $1; }
- X ;
- X
- X
- re2 : re '/'
- X {
- X /* this rule is separate from the others for "re" so
- X * that the reduction will occur before the trailing
- X * series is parsed
- X */
- X
- X if ( trlcontxt )
- X synerr( "trailing context used twice" );
- X else
- X trlcontxt = true;
- X
- X if ( varlength )
- X /* the trailing context had better be fixed-length */
- X varlength = false;
- X else
- X headcnt = rulelen;
- X
- X rulelen = 0;
- X $$ = $1;
- X }
- X ;
- X
- series : series singleton
- X {
- X /* this is where concatenation of adjacent patterns
- X * gets done
- X */
- X $$ = link_machines( $1, $2 );
- X }
- X
- X | singleton
- X { $$ = $1; }
- X ;
- X
- singleton : singleton '*'
- X {
- X varlength = true;
- X
- X $$ = mkclos( $1 );
- X }
- X
- X | singleton '+'
- X {
- X varlength = true;
- X
- X $$ = mkposcl( $1 );
- X }
- X
- X | singleton '?'
- X {
- X varlength = true;
- X
- X $$ = mkopt( $1 );
- X }
- X
- X | singleton '{' NUMBER ',' NUMBER '}'
- X {
- X varlength = true;
- X
- X if ( $3 > $5 || $3 <= 0 )
- X {
- X synerr( "bad iteration values" );
- X $$ = $1;
- X }
- X else
- X $$ = mkrep( $1, $3, $5 );
- X }
- X
- X | singleton '{' NUMBER ',' '}'
- X {
- X varlength = true;
- X
- X if ( $3 <= 0 )
- X {
- X synerr( "iteration value must be positive" );
- X $$ = $1;
- X }
- X
- X else
- X $$ = mkrep( $1, $3, INFINITY );
- X }
- X
- X | singleton '{' NUMBER '}'
- X {
- X /* the singleton could be something like "(foo)",
- X * in which case we have no idea what its length
- X * is, so we punt here.
- X */
- X varlength = true;
- X
- X if ( $3 <= 0 )
- X {
- X synerr( "iteration value must be positive" );
- X $$ = $1;
- X }
- X
- X else
- X $$ = link_machines( $1, copysingl( $1, $3 - 1 ) );
- X }
- X
- X | '.'
- X {
- X if ( ! madeany )
- X {
- X /* create the '.' character class */
- X anyccl = cclinit();
- X ccladd( anyccl, '\n' );
- X cclnegate( anyccl );
- X
- X if ( useecs )
- X mkeccl( ccltbl + cclmap[anyccl],
- X ccllen[anyccl], nextecm,
- X ecgroup, CSIZE );
- X
- X madeany = true;
- X }
- X
- X ++rulelen;
- X
- X $$ = mkstate( -anyccl );
- X }
- X
- X | fullccl
- X {
- X if ( ! cclsorted )
- X /* sort characters for fast searching. We use a
- X * shell sort since this list could be large.
- X */
- X cshell( ccltbl + cclmap[$1], ccllen[$1] );
- X
- X if ( useecs )
- X mkeccl( ccltbl + cclmap[$1], ccllen[$1],
- X nextecm, ecgroup, CSIZE );
- X
- X ++rulelen;
- X
- X $$ = mkstate( -$1 );
- X }
- X
- X | PREVCCL
- X {
- X ++rulelen;
- X
- X $$ = mkstate( -$1 );
- X }
- X
- X | '"' string '"'
- X { $$ = $2; }
- X
- X | '(' re ')'
- X { $$ = $2; }
- X
- X | CHAR
- X {
- X ++rulelen;
- X
- X if ( $1 == '\0' )
- X synerr( "null in rule" );
- X
- X if ( caseins && $1 >= 'A' && $1 <= 'Z' )
- X $1 = clower( $1 );
- X
- X $$ = mkstate( $1 );
- X }
- X ;
- X
- fullccl : '[' ccl ']'
- X { $$ = $2; }
- X
- X | '[' '^' ccl ']'
- X {
- X /* *Sigh* - to be compatible Unix lex, negated ccls
- X * match newlines
- X */
- X#ifdef NOTDEF
- X ccladd( $3, '\n' ); /* negated ccls don't match '\n' */
- X cclsorted = false; /* because we added the newline */
- X#endif
- X cclnegate( $3 );
- X $$ = $3;
- X }
- X ;
- X
- ccl : ccl CHAR '-' CHAR
- X {
- X if ( $2 > $4 )
- X synerr( "negative range in character class" );
- X
- X else
- X {
- X if ( caseins )
- X {
- X if ( $2 >= 'A' && $2 <= 'Z' )
- X $2 = clower( $2 );
- X if ( $4 >= 'A' && $4 <= 'Z' )
- X $4 = clower( $4 );
- X }
- X
- X for ( i = $2; i <= $4; ++i )
- X ccladd( $1, i );
- X
- X /* keep track if this ccl is staying in alphabetical
- X * order
- X */
- X cclsorted = cclsorted && ($2 > lastchar);
- X lastchar = $4;
- X }
- X
- X $$ = $1;
- X }
- X
- X | ccl CHAR
- X {
- X if ( caseins )
- X if ( $2 >= 'A' && $2 <= 'Z' )
- X $2 = clower( $2 );
- X
- X ccladd( $1, $2 );
- X cclsorted = cclsorted && ($2 > lastchar);
- X lastchar = $2;
- X $$ = $1;
- X }
- X
- X |
- X {
- X cclsorted = true;
- X lastchar = 0;
- X $$ = cclinit();
- X }
- X ;
- X
- string : string CHAR
- X {
- X if ( caseins )
- X if ( $2 >= 'A' && $2 <= 'Z' )
- X $2 = clower( $2 );
- X
- X ++rulelen;
- X
- X $$ = link_machines( $1, mkstate( $2 ) );
- X }
- X
- X |
- X { $$ = mkstate( SYM_EPSILON ); }
- X ;
- X
- X%%
- X
- X/* synerr - report a syntax error
- X *
- X * synopsis
- X * char str[];
- X * synerr( str );
- X */
- X
- synerr( str )
- char str[];
- X
- X {
- X syntaxerror = true;
- X fprintf( stderr, "Syntax error at line %d: %s\n", linenum, str );
- X }
- X
- X
- X/* yyerror - eat up an error message from the parser
- X *
- X * synopsis
- X * char msg[];
- X * yyerror( msg );
- X */
- X
- yyerror( msg )
- char msg[];
- X
- X {
- X }
- END_OF_FILE
- if test 8861 -ne `wc -c <'parse.y'`; then
- echo shar: \"'parse.y'\" unpacked with wrong size!
- fi
- # end of 'parse.y'
- fi
- if test -f 'sym.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sym.c'\"
- else
- echo shar: Extracting \"'sym.c'\" \(6087 characters\)
- sed "s/^X//" >'sym.c' <<'END_OF_FILE'
- X/* sym - symbol table routines */
- X
- X/*
- X * Copyright (c) 1987, the University of California
- X *
- X * The United States Government has rights in this work pursuant to
- X * contract no. DE-AC03-76SF00098 between the United States Department of
- X * Energy and the University of California.
- X *
- X * This program may be redistributed. Enhancements and derivative works
- X * may be created provided the new works, if made available to the general
- X * public, are made available for use by anyone.
- X */
- X
- X#include "flexdef.h"
- X
- struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
- struct hash_entry *sctbl[START_COND_HASH_SIZE];
- struct hash_entry *ccltab[CCL_HASH_SIZE];
- X
- struct hash_entry *findsym();
- X
- X
- X/* addsym - add symbol and definitions to symbol table
- X *
- X * synopsis
- X * char sym[], *str_def;
- X * int int_def;
- X * hash_table table;
- X * int table_size;
- X * 0 / -1 = addsym( sym, def, int_def, table, table_size );
- X *
- X * -1 is returned if the symbol already exists, and the change not made.
- X */
- X
- int addsym( sym, str_def, int_def, table, table_size )
- register char sym[];
- char *str_def;
- int int_def;
- hash_table table;
- int table_size;
- X
- X {
- X int hash_val = hashfunct( sym, table_size );
- X register struct hash_entry *entry = table[hash_val];
- X register struct hash_entry *new_entry;
- X register struct hash_entry *successor;
- X char *malloc();
- X
- X while ( entry )
- X {
- X if ( ! strcmp( sym, entry->name ) )
- X { /* entry already exists */
- X return ( -1 );
- X }
- X
- X entry = entry->next;
- X }
- X
- X /* create new entry */
- X new_entry = (struct hash_entry *) malloc( sizeof( struct hash_entry ) );
- X
- X if ( new_entry == NULL )
- X flexfatal( "symbol table memory allocation failed" );
- X
- X if ( (successor = table[hash_val]) )
- X {
- X new_entry->next = successor;
- X successor->prev = new_entry;
- X }
- X else
- X new_entry->next = NULL;
- X
- X new_entry->prev = NULL;
- X new_entry->name = sym;
- X new_entry->str_val = str_def;
- X new_entry->int_val = int_def;
- X
- X table[hash_val] = new_entry;
- X
- X return ( 0 );
- X }
- X
- X
- X/* cclinstal - save the text of a character class
- X *
- X * synopsis
- X * char ccltxt[];
- X * int cclnum;
- X * cclinstal( ccltxt, cclnum );
- X */
- X
- cclinstal( ccltxt, cclnum )
- char ccltxt[];
- int cclnum;
- X
- X {
- X /* we don't bother checking the return status because we are not called
- X * unless the symbol is new
- X */
- X char *copy_string();
- X
- X (void) addsym( copy_string( ccltxt ), (char *) 0, cclnum,
- X ccltab, CCL_HASH_SIZE );
- X }
- X
- X
- X/* ccllookup - lookup the number associated with character class text
- X *
- X * synopsis
- X * char ccltxt[];
- X * int ccllookup, cclval;
- X * cclval/0 = ccllookup( ccltxt );
- X */
- X
- int ccllookup( ccltxt )
- char ccltxt[];
- X
- X {
- X return ( findsym( ccltxt, ccltab, CCL_HASH_SIZE )->int_val );
- X }
- X
- X
- X/* findsym - find symbol in symbol table
- X *
- X * synopsis
- X * char sym[];
- X * hash_table table;
- X * int table_size;
- X * struct hash_entry *entry, *findsym();
- X * entry = findsym( sym, table, table_size );
- X */
- X
- struct hash_entry *findsym( sym, table, table_size )
- register char sym[];
- hash_table table;
- int table_size;
- X
- X {
- X register struct hash_entry *entry = table[hashfunct( sym, table_size )];
- X static struct hash_entry empty_entry =
- X {
- X (struct hash_entry *) 0, (struct hash_entry *) 0, NULL, NULL, 0,
- X } ;
- X
- X while ( entry )
- X {
- X if ( ! strcmp( sym, entry->name ) )
- X return ( entry );
- X entry = entry->next;
- X }
- X
- X return ( &empty_entry );
- X }
- X
- X
- X/* hashfunct - compute the hash value for "str" and hash size "hash_size"
- X *
- X * synopsis
- X * char str[];
- X * int hash_size, hash_val;
- X * hash_val = hashfunct( str, hash_size );
- X */
- X
- int hashfunct( str, hash_size )
- register char str[];
- int hash_size;
- X
- X {
- X register int hashval;
- X register int locstr;
- X
- X hashval = 0;
- X locstr = 0;
- X
- X while ( str[locstr] )
- X hashval = ((hashval << 1) + str[locstr++]) % hash_size;
- X
- X return ( hashval );
- X }
- X
- X
- X/* ndinstal - install a name definition
- X *
- X * synopsis
- X * char nd[], def[];
- X * ndinstal( nd, def );
- X */
- X
- ndinstal( nd, def )
- char nd[], def[];
- X
- X {
- X char *copy_string();
- X
- X if ( addsym( copy_string( nd ), copy_string( def ), 0,
- X ndtbl, NAME_TABLE_HASH_SIZE ) )
- X synerr( "name defined twice" );
- X }
- X
- X
- X/* ndlookup - lookup a name definition
- X *
- X * synopsis
- X * char nd[], *def;
- X * char *ndlookup();
- X * def/NULL = ndlookup( nd );
- X */
- X
- char *ndlookup( nd )
- char nd[];
- X
- X {
- X return ( findsym( nd, ndtbl, NAME_TABLE_HASH_SIZE )->str_val );
- X }
- X
- X
- X/* scinstal - make a start condition
- X *
- X * synopsis
- X * char str[];
- X * int xcluflg;
- X * scinstal( str, xcluflg );
- X *
- X * NOTE
- X * the start condition is Exclusive if xcluflg is true
- X */
- X
- scinstal( str, xcluflg )
- char str[];
- int xcluflg;
- X
- X {
- X char *copy_string();
- X
- X /* bit of a hack. We know how the default start-condition is
- X * declared, and don't put out a define for it, because it
- X * would come out as "#define 0 1"
- X */
- X /* actually, this is no longer the case. The default start-condition
- X * is now called "INITIAL". But we keep the following for the sake
- X * of future robustness.
- X */
- X
- X if ( strcmp( str, "0" ) )
- X printf( "#define %s %d\n", str, lastsc * 2 );
- X
- X if ( ++lastsc >= current_max_scs )
- X {
- X current_max_scs += MAX_SCS_INCREMENT;
- X
- X ++num_reallocs;
- X
- X scset = reallocate_integer_array( scset, current_max_scs );
- X scbol = reallocate_integer_array( scbol, current_max_scs );
- X scxclu = reallocate_integer_array( scxclu, current_max_scs );
- X actvsc = reallocate_integer_array( actvsc, current_max_scs );
- X }
- X
- X if ( addsym( copy_string( str ), (char *) 0, lastsc,
- X sctbl, START_COND_HASH_SIZE ) )
- X lerrsf( "start condition %s declared twice", str );
- X
- X scset[lastsc] = mkstate( SYM_EPSILON );
- X scbol[lastsc] = mkstate( SYM_EPSILON );
- X scxclu[lastsc] = xcluflg;
- X }
- X
- X
- X/* sclookup - lookup the number associated with a start condition
- X *
- X * synopsis
- X * char str[], scnum;
- X * int sclookup;
- X * scnum/0 = sclookup( str );
- X */
- X
- int sclookup( str )
- char str[];
- X
- X {
- X return ( findsym( str, sctbl, START_COND_HASH_SIZE )->int_val );
- X }
- END_OF_FILE
- if test 6087 -ne `wc -c <'sym.c'`; then
- echo shar: \"'sym.c'\" unpacked with wrong size!
- fi
- # end of 'sym.c'
- fi
- if test -f 'yylex.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'yylex.c'\"
- else
- echo shar: Extracting \"'yylex.c'\" \(3554 characters\)
- sed "s/^X//" >'yylex.c' <<'END_OF_FILE'
- X/* yylex - scanner front-end for flex */
- X
- X#include "flexdef.h"
- X#include "parse.h"
- X
- X/*
- X * Copyright (c) 1987, the University of California
- X *
- X * The United States Government has rights in this work pursuant to
- X * contract no. DE-AC03-76SF00098 between the United States Department of
- X * Energy and the University of California.
- X *
- X * This program may be redistributed. Enhancements and derivative works
- X * may be created provided the new works, if made available to the general
- X * public, are made available for use by anyone.
- X */
- X
- X/* yylex - scan for a regular expression token
- X *
- X * synopsis
- X *
- X * token = yylex();
- X *
- X * token - return token found
- X */
- X
- int yylex()
- X
- X {
- X int toktype;
- X static int beglin = false;
- X
- X if ( eofseen )
- X toktype = EOF;
- X else
- X toktype = flexscan();
- X
- X if ( toktype == EOF )
- X {
- X eofseen = 1;
- X
- X if ( sectnum == 1 )
- X {
- X synerr( "unexpected EOF" );
- X sectnum = 2;
- X toktype = SECTEND;
- X }
- X
- X else if ( sectnum == 2 )
- X {
- X sectnum = 3;
- X toktype = SECTEND;
- X }
- X
- X else
- X toktype = 0;
- X }
- X
- X if ( trace )
- X {
- X if ( beglin )
- X {
- X fprintf( stderr, "%d\t", accnum + 1 );
- X beglin = 0;
- X }
- X
- X switch ( toktype )
- X {
- X case '<':
- X case '>':
- X case '^':
- X case '$':
- X case '"':
- X case '[':
- X case ']':
- X case '{':
- X case '}':
- X case '|':
- X case '(':
- X case ')':
- X case '-':
- X case '/':
- X case '\\':
- X case '?':
- X case '.':
- X case '*':
- X case '+':
- X case ',':
- X (void) putc( toktype, stderr );
- X break;
- X
- X case '\n':
- X (void) putc( '\n', stderr );
- X
- X if ( sectnum == 2 )
- X beglin = 1;
- X
- X break;
- X
- X case SCDECL:
- X fputs( "%s", stderr );
- X break;
- X
- X case XSCDECL:
- X fputs( "%x", stderr );
- X break;
- X
- X case WHITESPACE:
- X (void) putc( ' ', stderr );
- X break;
- X
- X case SECTEND:
- X fputs( "%%\n", stderr );
- X
- X /* we set beglin to be true so we'll start
- X * writing out numbers as we echo rules. flexscan() has
- X * already assigned sectnum
- X */
- X
- X if ( sectnum == 2 )
- X beglin = 1;
- X
- X break;
- X
- X case NAME:
- X fprintf( stderr, "'%s'", nmstr );
- X break;
- X
- X case CHAR:
- X switch ( yylval )
- X {
- X case '<':
- X case '>':
- X case '^':
- X case '$':
- X case '"':
- X case '[':
- X case ']':
- X case '{':
- X case '}':
- X case '|':
- X case '(':
- X case ')':
- X case '-':
- X case '/':
- X case '\\':
- X case '?':
- X case '.':
- X case '*':
- X case '+':
- X case ',':
- X fprintf( stderr, "\\%c", yylval );
- X break;
- X
- X case 1:
- X case 2:
- X case 3:
- X case 4:
- X case 5:
- X case 6:
- X case 7:
- X case 8:
- X case 9:
- X case 10:
- X case 11:
- X case 12:
- X case 13:
- X case 14:
- X case 15:
- X case 16:
- X case 17:
- X case 18:
- X case 19:
- X case 20:
- X case 21:
- X case 22:
- X case 23:
- X case 24:
- X case 25:
- X case 26:
- X case 27:
- X case 28:
- X case 29:
- X case 30:
- X case 31:
- X fprintf( stderr, "^%c", 'A' + yylval - 1 );
- X break;
- X
- X case 127:
- X (void) putc( '^', stderr );
- X (void) putc( '@', stderr );
- X break;
- X
- X default:
- X (void) putc( yylval, stderr );
- X break;
- X }
- X
- X break;
- X
- X case NUMBER:
- X fprintf( stderr, "%d", yylval );
- X break;
- X
- X case PREVCCL:
- X fprintf( stderr, "[%d]", yylval );
- X break;
- X
- X case 0:
- X fprintf( stderr, "End Marker" );
- X break;
- X
- X default:
- X fprintf( stderr, "*Something Weird* - tok: %d val: %d\n",
- X toktype, yylval );
- X break;
- X }
- X }
- X
- X return ( toktype );
- X }
- END_OF_FILE
- if test 3554 -ne `wc -c <'yylex.c'`; then
- echo shar: \"'yylex.c'\" unpacked with wrong size!
- fi
- # end of 'yylex.c'
- fi
- echo shar: End of archive 1 \(of 5\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 5 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-